import { Component, OnInit, Output, Input, EventEmitter, TemplateRef, ViewChild } from '@angular/core';
import { IdService } from '@farris/ui-common';
import { DatagridComponent } from '@farris/ui-datagrid';
import { EditorTypes } from '@farris/ui-datagrid-editors';
import { NotifyService } from '@farris/ui-notify';
import { TreeNode } from '@farris/ui-treetable';
import { MappingFieldManager, SelectMappingEditorParam } from './mapping-field-manager';



/**
 * 映射选择器：元数据与当前表单字段之前的映射
 */
@Component({
  selector: 'app-select-mapping',
  templateUrl: './select-mapping.component.html',
  styleUrls: ['./select-mapping.component.css'],
  providers: [MappingFieldManager]
})
export class SelectMappingComponent implements OnInit {

  @Output() closeModal = new EventEmitter<any>();

  /** 模态框确定后关闭，并传递参数 */
  @Output() submitModal = new EventEmitter<any>();

  /** 映射值：  "{'id':'company.company','name':'company.company_Name'}" */
  @Input() value: string;

  /** 编辑器参数 */
  @Input() editorParams: SelectMappingEditorParam;

  /** 模态框页脚 */
  @ViewChild('mappingFooter') modalFooter: TemplateRef<any>;

  /** 模态框配置数据 */
  modalConfig = { title: '映射编辑器', width: 900, height: 500, showButtons: true };

  /** 源元数据类型，默认为帮助元数据 */
  sourceMetadataType = 'help';

  /** 源元数据显示名称 */
  sourceMetadataName = '参照字段';

  /** 列表组件实例 */
  @ViewChild(DatagridComponent) dataGridCmp: DatagridComponent;

  /** 映射数组 */
  mapValues = [];

  /** 列表列配置 */
  dataGridCols: any[] = [
    { field: 'sourceLabel', title: this.sourceMetadataName, editor: { type: EditorTypes.COMBOLOOKUP, options: { panelWidth: 'auto' } } },
    { field: 'targetLabel', title: '目标字段', editor: { type: EditorTypes.COMBOLOOKUP, options: { panelWidth: 'auto' } } }];

  /** 源字段下拉树表数据 */
  sourceFieldTreeData: TreeNode[] = [];

  /** 目标字段下拉树表数据 */
  targetFieldTreeData: TreeNode[] = [];

  constructor(
    private idService: IdService,
    private managerService: MappingFieldManager,
    private notifyService: NotifyService) { }

  ngOnInit() {
    if (this.value) {
      this.convertMapStr2Array();
    }
    this.sourceMetadataType = this.editorParams.sourceMetadataType || 'help';
    // this.sourceMetadataName = (this.editorParams.sourceMetadataName || '帮助') + '字段';


    if (!this.editorParams || !this.editorParams.sourceMetadataId) {
      this.notifyService.warning('请先选择' + this.sourceMetadataName + '元数据！');
      return;
    }
    if (!this.editorParams || !this.editorParams.binding || !this.editorParams.binding.type) {
      this.notifyService.warning('请先绑定字段或变量！');
      return;
    }

    this.setSourceDataGridColumnConfig();

    this.setTargetDataGridColumn();
  }

  /**
   * 配置源字段列
   */
  private setSourceDataGridColumnConfig() {
    this.managerService.assembleSourceFields(this.editorParams).subscribe(data => {
      this.sourceFieldTreeData = data || [];

      this.dataGridCols[0].editor = {
        type: EditorTypes.COMBOLOOKUP,
        options: {
          idField: 'bindingPath', valueField: 'bindingPath', textField: 'bindingPath', data: this.sourceFieldTreeData,
          columns: [{ field: 'name', title: '名称' }, { field: 'bindingPath', title: '绑定' }],
          editable: false,
          enableClear: false,
          multiSelect: false,
          displayType: 'LOOKUPTREELIST',
          autoWidth: true
        }
      };

    });

  }

  /**
   * 配置目标字段列
   */
  private setTargetDataGridColumn() {
    const isMultiSelect = (this.editorParams && this.editorParams.isMultiSelect) === false ? false : true;
    this.targetFieldTreeData = this.managerService.assembleTargetFields(this.editorParams.binding, this.editorParams.viewModelId);
    this.dataGridCols[1].editor = {
      type: EditorTypes.COMBOLOOKUP,
      options: {
        idField: 'bindingPath', valueField: 'bindingPath', textField: 'bindingPath', data: this.targetFieldTreeData,
        columns: [{ field: 'name', title: '名称' }, { field: 'bindingPath', title: '绑定' }],
        editable: false,
        enableClear: false,
        enableCancelSelected: false,
        multiSelect: isMultiSelect,
        displayType: 'LOOKUPTREELIST',
        autoWidth: true
      }
    };
  }

  /**
   * 将映射字符串转为dataGrid所需的数组结构
   */
  private convertMapStr2Array() {
    let mapObject;
    try {
      const regExp = new RegExp('\'', 'g');
      const value = this.value.replace(regExp, '\"');
      mapObject = JSON.parse(value);
      const sourceLabels = Object.keys(mapObject);
      if (sourceLabels.length === 0) {
        return;
      }
      sourceLabels.forEach(sourceLabel => {
        const targetLabel = mapObject[sourceLabel];
        this.mapValues.push({
          id: this.idService.generate(),
          sourceLabel,
          targetLabel
        });

      });
    } catch (error) {
      this.notifyService.error('mapFields 格式错误！！');
    }


  }

  /**
   * 新增映射
   */
  addMapping() {
    // 触发单元格结束编辑
    this.dataGridCmp.endEditing();

    this.mapValues.push({
      id: this.idService.generate(),
      sourceLabel: '',
      targetLabel: ''
    });
    this.dataGridCmp.loadData(this.mapValues);
  }

  /**
   * 移除映射
   */
  removeMapping() {
    const row = this.dataGridCmp.selectedRow;
    if (!row) {
      this.notifyService.warning('请先选中要删除的映射。');
      return;
    }

    const rowIndex = row.index;
    this.mapValues.splice(rowIndex, 1);

    this.dataGridCmp.loadData(this.mapValues);
    this.dataGridCmp.clearAll();

    // 自动选中下一行
    if (this.mapValues.length) {
      const targetRowIndex = rowIndex >= this.mapValues.length ? 0 : rowIndex;
      this.dataGridCmp.selectRow(this.mapValues[targetRowIndex].id);
    }


  }
  clickCancel() {
    this.closeModal.emit();
  }

  clickConfirm() {
    this.dataGridCmp.endEditing();
    if (this.mapValues.length === 0) {
      this.submitModal.emit({ value: '' });
      return;
    }
    // 校验源字段是否重复
    const keyValues = this.mapValues.map(v => v.sourceLabel);
    const keySet = new Set(keyValues);
    const exclusiveKeys = Array.from(keySet);
    if (this.mapValues.length !== exclusiveKeys.length) {
      this.notifyService.warning(this.sourceMetadataName + '重复，请重新选择。');
      return;
    }
    for (const mapValue of this.mapValues) {
      if (!mapValue.sourceLabel) {
        this.notifyService.warning(this.sourceMetadataName + '不能为空。');
        return;
      }
      if (!mapValue.targetLabel) {
        this.notifyService.warning('目标字段不能为空。');
        return;
      }
    }
    const mapObject = {};
    this.mapValues.forEach(map => {
      mapObject[map.sourceLabel] = map.targetLabel;
    });
    let mapStr = JSON.stringify(mapObject);
    const regExp = new RegExp('\"', 'g');
    mapStr = mapStr.replace(regExp, '\'');

    this.submitModal.emit({ value: mapStr });

  }


  /**
   * 将字段bindingPath转为名称显示在非编辑态的DataGrid单元格里。因为编辑态无法实现展示名称，故列表目前显示的是字段bindingPath
   */
  // private getFieldNameByBindingPath(flag: 'source' | 'target', bindingPath: string) {
  //   const treeData = flag === 'source' ? this.sourceFieldTreeData : this.targetFieldTreeData;
  //   const data = this.findNodeByBindingPath(treeData, bindingPath);
  //   if (data && data.name) {
  //     return data.name;
  //   }
  //   return bindingPath;
  // }

  // private findNodeByBindingPath(treeData: TreeNode[], bindingPath: string) {
  //   for (const treeNode of treeData) {
  //     if (treeNode.data.bindingPath === bindingPath) {
  //       return treeNode.data;
  //     }

  //     if (treeNode.children && treeNode.children.length) {
  //       const data = this.findNodeByBindingPath(treeNode.children, bindingPath);
  //       if (data) {
  //         return data;
  //       }
  //     }
  //   }
  // }
}
